package projet1;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Operators
{
    public static void mult(NodeStack stack)
    {
        assert stack.top().getValue() instanceof Float : "Erreur fatale les données sont pas des nombres";
        float one = (Float) stack.pop();
        assert stack.top().getValue() instanceof Float : "Erreur fatale les données sont pas des nombres(2)";
        float two = (Float) stack.pop();

        stack.push(one * two);
    }

    public static void div(NodeStack stack)
    {
        assert stack.top().getValue() instanceof Float : "Erreur fatale les données sont pas des nombres";
        float one = (Float) stack.pop();
        assert stack.top().getValue() instanceof Float : "Erreur fatale les données sont pas des nombres(2)";
        float two = (Float) stack.pop();

        assert one != 0.0 : "Divide by 0 !!";

        stack.push(two / one);
    }

    public static void add(NodeStack stack)
    {
        assert stack.top().getValue() instanceof Float : "Erreur fatale les données sont pas des nombres";
        float one = (Float) stack.pop();
        assert stack.top().getValue() instanceof Float : "Erreur fatale les données sont pas des nombres(2)";
        float two = (Float) stack.pop();

        stack.push(one + two);
    }

    public static void sub(NodeStack stack)
    {
        assert stack.top().getValue() instanceof Float : "Erreur fatale les données sont pas des nombres";
        float one = (Float) stack.pop();
        assert stack.top().getValue() instanceof Float : "Erreur fatale les données sont pas des nombres(2)";
        float two = (Float) stack.pop();

        stack.push(one - two);
    }

    public static void dup(NodeStack stack)
    {
        Object one = stack.top().getValue();
        stack.push(one);
    }

    public static void exch(NodeStack stack)
    {
        Object one = stack.pop();
        Object two = stack.pop();
        stack.push(one);
        stack.push(two);
    }

    private static boolean compareTwoFirsts(NodeStack stack)
    {
        if (stack.top().getValue() instanceof Float)
        {
            float one = (Float) stack.pop();
            assert stack.top().getValue() instanceof Float : "La deuxième donnée de eq n'est pas un entier bug";
            float two = (Float) stack.pop();

            return one == two;
        }
        else if (stack.top().getValue() instanceof String)
        {
            String one = (String) stack.pop();
            assert stack.top().getValue() instanceof String : "La deuxième donnée de eq n'est pas un string bug";
            String two = (String) stack.pop();

            return one.equals(two);
        }
        throw new AssertionError("BUUUG /!\\ la methode d'égalité n'est pas à cet effet");
    }

    /*
     * @pre compare 2 strings ou deux entiers
     */
    public static void eq(NodeStack stack)
    {
        stack.push(compareTwoFirsts(stack));
    }

    public static void ne(NodeStack stack)
    {
        stack.push(!compareTwoFirsts(stack));
    }

    public static void pstack(NodeStack stack)
    {
        Node curseur = stack.top();
        try
        {
            while (curseur != null)
            {

                Utils.writeTextInFile(Projet1.outFile, curseur.getValue().toString() + "\n", false);
                curseur = curseur.getNext();
            }
        }
        catch (FileNotFoundException ex)
        {
            ex.printStackTrace();
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
    }

    /*
     * Cette méthode ne correspond pas tout à fait à la réalité dans Post-Script mais a été simplifiée pour
     * fonctionner avec les exemples du cours
     */
    public static void def(NodeStack stack)
    {
        Object value = stack.pop();
        Object key = stack.top().getValue();
        assert key instanceof String : "Erreur dans def";
        assert ((String)key).charAt(0) == '/' : "Mauvaise structure de définition";
        stack.pop();
        
        Symboles.addSymbole(((String)key).substring(1), value);
    }
}